import tkinter as tk
from tkinter import messagebox, ttk, scrolledtext, Menu
import requests
import threading

# Токен для доступа к VK API
TOKEN = "vk1.a.wlRmdntrZmzFxiaGl_3L6RDuzJx61lcC607fiLxPd72SPEAwTBXkKOkHr9zCeAyFWHu0oWkEKFg0NuL3d9uouXF4HGT8nqkK4YHb2c4j5zgdnikpHN9nRqlTz0psHIMkD7cExviVDTRTcnGgX4pc5SED1NHpGp2Tyt8f5F7KY1jLINZ7fFhOOmg2DTYRhmw_zGESA6NZ7jSFZA2zDo1QeQ"

# Словарь для сопоставления английских значений с русскими
category_translation = {
    'all': 'Все',
    'friends_of_friends': 'Друзья друзей',
    'friends': 'Друзья',
    'only_me': 'Только я',
    'some': 'Некоторые',
    'nobody': 'Никто',
    'all_except_of_search_engines': 'Все, кроме поисковых систем',
    'vk_users_only': 'Только пользователи VK',
    'see_all_friends': 'Все друзья',
    'closed': 'Закрытый профиль',
    'open': 'Открытый профиль'
}

# Обратный словарь для преобразования русских значений обратно в английские
reverse_category_translation = {v: k for k, v in category_translation.items()}

# Функция для перевода значений на русский
def translate_category(category, reverse=False):
    if reverse:
        return reverse_category_translation.get(category, category)
    else:
        return category_translation.get(category, category)

# Функция для записи в журнал
def log_message(message):
    log_text.configure(state='normal')  # Разрешить редактирование текстового поля
    log_text.insert(tk.END, message + '\n')
    log_text.configure(state='disabled')  # Запретить редактирование текстового поля
    log_text.yview(tk.END)  # Прокрутить журнал к последнему сообщению

# Функция для получения настроек приватности пользователя
def get_privacy_settings():
    try:
        url = 'https://api.vk.com/method/account.getPrivacySettings'
        params = {
            'access_token': TOKEN,
            'v': '5.131'
        }
        response = requests.get(url, params=params)
        data = response.json()
        if 'error' in data:
            error_msg = f"Ошибка VK API: {data['error']['error_msg']}"
            log_message(f"Ошибка: {error_msg}")
            return None
        log_message("Настройки приватности успешно загружены.")
        return data['response']['settings']
    except Exception as e:
        error_msg = f"Произошла ошибка: {str(e)}"
        log_message(f"Ошибка: {error_msg}")
        return None

# Функция для получения типа профиля (открытый или закрытый)
def get_profile_type():
    try:
        url = 'https://api.vk.com/method/account.getProfileInfo'
        params = {
            'access_token': TOKEN,
            'v': '5.131'
        }
        response = requests.get(url, params=params)
        data = response.json()
        if 'error' in data:
            error_msg = f"Ошибка VK API: {data['error']['error_msg']}"
            log_message(f"Ошибка: {error_msg}")
            return None
        # Определяем "Тип профиля"
        profile_type = "Закрытый" if data['response'].get('is_closed') else "Открытый"
        return profile_type
    except Exception as e:
        error_msg = f"Произошла ошибка при получении типа профиля: {str(e)}"
        log_message(f"Ошибка: {error_msg}")
        return None

# Функция для обновления интерфейса с настройками
def update_settings(settings, profile_type):
    if settings:
        # Очистка таблицы перед обновлением
        for i in tree.get_children():
            tree.delete(i)
        
        # Очистка предыдущих виджетов с combobox
        for widget in combobox_frame.winfo_children():
            widget.destroy()
        
        # Сохранение текущих значений combobox
        combobox_vars.clear()

        # Добавление настройки типа профиля
        profile_type_title = "0. Тип профиля"
        item_id = tree.insert("", "end", values=(profile_type_title, profile_type))
        var = tk.StringVar(value=profile_type)
        combobox_vars[item_id] = var
        combobox = ttk.Combobox(combobox_frame, textvariable=var, values=['Открытый профиль', 'Закрытый профиль'], state="readonly")
        combobox.grid(row=0, column=0, pady=5, sticky='w')
        combobox_list[item_id] = combobox
        log_message(f"Загружен {profile_type_title}: {profile_type}")

        # Добавление других настроек в таблицу
        row = 1
        for idx, setting in enumerate(settings, 1):
            key = setting.get('key', 'Нет данных')
            title = f"{idx}. {setting.get('title', 'Нет данных')}"  # Нумерация настройки
            value = setting.get('value', {}).get('category', 'Нет данных')
            supported_categories = setting.get('supported_categories', [])

            # Перевод значений на русский язык
            translated_value = translate_category(value)
            translated_categories = [translate_category(cat) for cat in supported_categories]

            # Добавляем только нужные параметры
            if key in relevant_settings:
                # Добавляем строку в таблицу
                item_id = tree.insert("", "end", values=(title, translated_value))

                # Создаем переменную для хранения выбранного значения
                var = tk.StringVar(value=translated_value)
                combobox_vars[item_id] = var

                # Добавляем выпадающее меню для изменения значения
                combobox = ttk.Combobox(combobox_frame, textvariable=var, values=translated_categories, state="readonly")
                combobox.grid(row=row, column=0, pady=5, sticky='w')
                combobox_list[item_id] = combobox
                row += 1

        log_message("Настройки приватности успешно загружены и отображены.")

# Функция для загрузки настроек в отдельном потоке
def load_settings_thread():
    log_message("Загрузка настроек приватности и типа профиля...")
    settings = get_privacy_settings()
    profile_type = get_profile_type()
    root.after(0, update_settings, settings, profile_type)

# Функция для сохранения изменений в отдельном потоке
def save_changes_thread():
    log_message("Сохранение изменений настроек приватности...")
    for item_id, var in combobox_vars.items():
        selected_value = var.get()
        translated_value = translate_category(selected_value, reverse=True)
        title, current_value = tree.item(item_id, 'values')
        
        # Извлекаем индекс настройки из заголовка
        index = title.split('.')[0]
        
        # Если индекс "0", это изменение типа профиля
        if index == "0":
            new_profile_type = 1 if translated_value == 'closed' else 0
            result = set_profile_type(new_profile_type)
            if result:
                log_message(f"Тип профиля успешно изменен на '{selected_value}'")
            continue
        
        # Найти настройку по названию
        for setting in get_privacy_settings():
            if title.split('.')[1].strip() == setting['title']:
                key = setting['key']
                
                # Проверка на наличие значения в списке поддерживаемых категорий
                supported_categories = setting.get('supported_categories', [])
                if translated_value not in supported_categories:
                    log_message(f"Ошибка: Значение '{translated_value}' не поддерживается для настройки {index}. '{setting['title']}'. Поддерживаемые значения: {supported_categories}")
                    continue
                
                # Обновить настройку через VK API
                result = set_privacy_setting(key, translated_value)
                if result:
                    log_message(f"Настройка {index}. '{setting['title']}' успешно обновлена на '{selected_value}'.")

# Функция для изменения типа профиля (открытый/закрытый)
def set_profile_type(is_closed):
    try:
        url = 'https://api.vk.com/method/account.setProfileInfo'
        params = {
            'is_closed': is_closed,
            'access_token': TOKEN,
            'v': '5.131'
        }
        response = requests.get(url, params=params)
        data = response.json()
        if 'error' in data:
            error_msg = f"Ошибка VK API при изменении типа профиля: {data['error']['error_msg']}"
            log_message(error_msg)
            return False
        return True
    except Exception as e:
        error_msg = f"Произошла ошибка при изменении типа профиля: {str(e)}"
        log_message(error_msg)
        return False

# Функция для обновления настройки приватности через VK API
def set_privacy_setting(key, value):
    try:
        url = 'https://api.vk.com/method/account.setPrivacy'
        params = {
            'key': key,
            'value': value,
            'access_token': TOKEN,
            'v': '5.131'
        }
        response = requests.get(url, params=params)
        data = response.json()
        if 'error' in data:
            error_msg = f"Ошибка VK API при обновлении настройки {key}: {data['error']['error_msg']}"
            log_message(error_msg)
            return False
        log_message(f"Настройка {key} успешно обновлена на {value}.")
        return True
    except Exception as e:
        error_msg = f"Произошла ошибка при обновлении настройки {key}: {str(e)}"
        log_message(error_msg)
        return False

# Функция для копирования выделенного текста из журнала
def copy_log_text(event=None):
    try:
        selected_text = log_text.selection_get()
        root.clipboard_clear()
        root.clipboard_append(selected_text)
    except tk.TclError:
        pass  # Ничего не делать, если нет выделенного текста

# Функция для создания контекстного меню в журнале
def create_context_menu():
    context_menu = Menu(log_text, tearoff=0)
    context_menu.add_command(label="Копировать", command=copy_log_text)
    return context_menu

# Инициализация окна приложения
root = tk.Tk()
root.title("Настройки приватности VK")
root.geometry("800x800")

# Рамка для ввода данных
frame_input = tk.Frame(root)
frame_input.pack(pady=10)

# Кнопка для загрузки настроек
button_load = tk.Button(frame_input, text="Загрузить настройки", command=lambda: threading.Thread(target=load_settings_thread).start())
button_load.pack(side=tk.LEFT, padx=5)

# Кнопка для сохранения изменений
button_save = tk.Button(frame_input, text="Сохранить изменения", command=lambda: threading.Thread(target=save_changes_thread).start())
button_save.pack(side=tk.LEFT, padx=5)

# Настройка таблицы для отображения данных
columns = ("title", "value")
tree = ttk.Treeview(root, columns=columns, show="headings", height=15)
tree.heading("title", text="Название настройки")
tree.heading("value", text="Значение")

# Установка ширины столбцов
tree.column("title", width=400)
tree.column("value", width=200)

tree.pack(pady=20)

# Фрейм для размещения combobox с использованием grid
combobox_frame = tk.Frame(root)
combobox_frame.pack(pady=10)

# Текстовое поле для отображения журнала
log_frame = tk.Frame(root)
log_frame.pack(fill=tk.BOTH, expand=True, pady=10)
log_text = scrolledtext.ScrolledText(log_frame, wrap=tk.WORD, height=10, state='disabled')
log_text.pack(fill=tk.BOTH, expand=True)

# Создание контекстного меню для текстового поля журнала
context_menu = create_context_menu()
log_text.bind("<Button-3>", lambda event: context_menu.post(event.x_root, event.y_root))

# Список релевантных настроек
relevant_settings = [
    "profile",  # Кто видит основную информацию моей страницы
    "replies_view",  # Кто видит комментарии к записям
    "status_replies",  # Кто может комментировать мои записи
    "mail_send",  # Кто может писать мне личные сообщения
    "wall_send",  # Кто может оставлять записи на моей странице
    "page_access",  # Кому в интернете видна моя страница
    "wall"  # Кто видит чужие записи на моей странице
]

# Словарь для хранения переменных StringVar для каждого выпадающего меню
combobox_vars = {}
combobox_list = {}

# Запуск основного цикла приложения
root.mainloop()
